2023 9월 회고

9월의 끝!

2023-10-03

9월은 프로젝트로만 꽉 이루어진 한 달이었다. 프로젝트를 하면서 좌절하는 순간도 많았고, 팀 프로젝트 상영회 당일에도 에러를 고쳐서 PR을 올렸을 정도로 한 달동안 프로젝트에만 집중했었던 것 같다.

옛날에는 단순히 개발을 잘하는 사람이면 되는거 아닌가? 또 뭐가 필요하지? 라는 생각이 많았었는데 요즘은 이런 생각보다는 같이 일하고 싶은 사람, 내가 만드는 것에 애정과 관심이 넘치는 사람, 뭔가 테스크가 주어지면 깔끔하게 딱 마무리가 되는 사람이 되고싶다는 생각을 많이 했다. (물론 이를 위해서는 개발도 잘 해야 겠지만 ..!)

또 미래의 내가 어떤 곳에서 개발을 하고 싶은지에 대해서도 생각이 많아지는 것 같다.(물론 붙여주면 절부터 하겠지만..!) 협업을 하면서 1+1이 10이 될수도 있고 1+1이 0.8이 될수도 있겠다..라는 생각을 했다. 그만큼 개발만 잘하면 끝이 아니라 어떻게 협업을하고 팀에 기여를 잘 할 수 있을까.. 하는 것도 최근에 많이 했던 고민이다..

기획

기획단계에서 정말 많은 이야기를 나눴고 여러 의견에 대해서 검토를 하게 되었다. 특히 어떤 것을 주제로 잡을지에 대해 끊임없이 아이디어를 냈는데

마크다운 이미지

이 외에도 정말 많은 의견이 나와서 이 중에 투표를 통해 최종적인 주제를 정했다.

우리는 각종 거래에 대한 평가와 피드백이 가능한 커뮤니티 사이트를 최종적으로 개발하기로 했다. 이것 이외에도 브랜치 전략에 대해서도 이야기를 나눴는데 동영 멘토님의 의견과 팀의 종합적인 의견은 git-flow는 너무 비대해지고 복잡하기도 할 것 같다는 의견과 빠르게빠르게 배포가능해야 하므로 각 이슈별로 feature 브랜치를 두고 스프린트별 배포를 담당할 release , 최종 배포를 위한 main으로 브랜치를 가져가기로 했다.

마크다운 이미지

Next js

이번 프로젝트에서 Next.js를 쓰기로 했다. Next를 쓴다면 러닝커브가 엄청 많이는 없을 것 같고 여러 랜더링 전략을 섞어서 잘 쓸 수 있을 거라는 기대감과 함께, 프레임워크로서의 어떤 규칙도 명확하다고 생각해서 도입을 하게 되었는데, 팀원분들 중에 Next.js에 대해 잘 모르는 분도 있어서, 지식의 싱크를 맞추기 위해, 발표를 준비했다. 당장 개발해야 하는데 , Next를 아예 모르면 좀 힘들것 같기도하고, 내가 Next를 배웠던 것들 + 추가적인 자료를 모아서 발표를 하게되었다.

다만 발표준비까지 기간이 너무 길어지면 안되기때문에 빠르게 이틀만에..발표를 했는데 너무 말을 잘 못한것 같기도 하다.!

그 당시의 발표자료..

개발 일정 산정

나영 멘토님의 특강을 듣고 팀원들과 개발 일정 산정을 하게되었다.

이 기능을 구현하기 위해서 내가 얼마만큼의 시간이 필요할지 의논하는 시간이 필요했다. 먼저 유저스토리를 쫙 놓고 ,

마크다운 이미지

해당 기능을 스프린트에서 얼마나의 시간동안 구현할 수 있을까? 를 고민하는 시간을 가졌다.

마크다운 이미지

지금생각하면 내 개발 속도를 잘 몰랐으니깐 저렇게 중구난방식으로 적었던 것 같은데, 생각보다 나의 개발속도는 느렸던 것 같다..

겪었던 이슈

배포를 하고 QA를 할때마다 내가 맡은 기능에 버그가 터져나오는 걸 보면서,, 내 멘탈도 같이 터져나갔던 것 같다. 처음 겪은 이슈는 정말정말 간단하다고 할 수 있는 노드버전문제다. 분명 같은 코든데 다른 팀원의 환경에서는 동작하고 내 로컬에서는 동작하지 않았다.

마크다운 이미지

(next 13버전을 쓰고 있었고 개발 당시 내 노드 버전은 18.1버전이었다.)

정말 왜 이러지? 뭐가 잘못된거지? 라는 생각을 계속하고 구글링을 계속 해도 해결책이 보이지 않았다.

멘토님께 상황을 설명드리고 정말 도저히 모르겠다... 왜 안되는지 이유라도 알고 싶다..라고 고민을 털어놓았고, 그 날 멘토님과 2시간가량 끙끙 앓았던 후,'노드 버전을 업데이트 해보실래요?'의 말을 듣고 노드 버전을 18.17.1로 업데이트를 하니깐..동작을 하였다..

진짜 설마 노드 버전이 원인이겠어...라는 생각을 했었는데 진짜였다..!

마크다운 이미지

(정말 감사드립니다 멘토님..)

좋아요와 싫어요의 기능 구현

꿀매인지 판단을 해주는 서비스 특성상, 피드백을 댓글로만 아니라 좋아요,싫어요로도 주면 좋겠다는 의견이 있었고, 좋아요,싫어요 기능을 도입하기로 했다. 문제는 주어진 API의 명세에는 좋아요 기능만 있지, 싫어요 기능은 존재하지 않는 상태였고, 이를 어떻게 해결해야 할지 막막함이 있었다.

여러 의견이 있었다. 자체 백엔드를 띄워서 해결해야하나? 주어진 명세에 없으니 이를 포기하고 건너뛰어야하나? 라는 의견이 주고받아졌고, 멘토님과의 커피챗이 있던 날 '채널을 통해 좋아요 싫어요를 구분할 수 있을 것 같다'라는 피드백을 받았고, 채널을 통해서 이 문제를 해결할 수 있을 것 같았다.

채널을 2개 만들고, 포스트 작성시 먼저 1번 채널에 생성 요청을 보내고 해당 요청으로 들어온 ID를 참조하는 필드를 둬서, 2번 채널에 포스트 생성 요청을 보낼때, 이를 참조하게끔 만들어서 기능적으로 해결할 수 있었다.

그 후 1번채널의 좋아요를 좋아요로 판단하고, 2번 채널의 좋아요를 싫어요로 판단하도록 하였다. (나머지 필드는 모두 동일하게 가져가고.!)

그림으로 나타내면,아래와 같다.!

마크다운 이미지

그러나..

이렇게 하면 구현이 끝날 줄 알았다. 그러나 QA에서, 사용자 상세 페이지나 검색을 하면 2개의 동일한 포스트가 나타나는 버그가 발견이 되었고, 해당 페이지들에서 채널을 한번 필터링 해줘야 하는 과정이 필요했다.

다행히 Next의 api route에서 실제 api를 찌르고 있었고 로직이 api route에 들어가게 되어서 실제 요청을 보내는 코드는 단순하게 가져가고, api route에서 로직을 다 처리하게 끔 해서, 되게 편하고 좋았던 것 같다.

//api route로 요청을 보냄
export const getUserPosts = async ({
  authorId,
  offset,
  limit,
}: {
  authorId: string
  offset: number
  limit: number
}) => {
  const { data } = await apiClient.get(
    `/api/posts/author?authorId=${authorId}&offset=${offset}&limit=${limit}`,
  )
  return data
}

이렇게 요청을 보내고 실제 api를 찌르는 쪽은 api route에서 이루어진다.!

//요기서 실제 api를 찌름
import { NextRequest, NextResponse } from 'next/server'
import { Environment } from '@/config/environments'
import { apiServer } from '@/lib/axiosSever'
import type Post from "@/types/post"

export async function GET(req: NextRequest) {
  const authorId = req.nextUrl.searchParams.get('authorId')
  const limit = Number(req.nextUrl.searchParams.get('limit'))
  const offset = Number(req.nextUrl.searchParams.get('offset'))

  try {
    const { data } = await apiServer.get(
      `/posts/author/${authorId}?offset=${offset}&limit=${limit}`,
    )

    //채널을 필터링해주는 과정이 필요함.!
    const targetPosts = data.filter(
      (post: Post) => post.channel._id === Environment.channelId(),
    )
    
    const parsedPosts = targetPosts.map((post: Post) => {
      const parsedArticle = JSON.parse(post.title)
      if (parsedArticle) {
        return {
          ...post,
          title: parsedArticle.title,
          description: parsedArticle.description,
          mapping_ID: parsedArticle.mapping_ID,
        }
      } else {
        return {
          ...post,
          description: '',
        }
      }
    })
    return NextResponse.json(parsedPosts)
  } catch (error: any) {
    return NextResponse.json(
      { error: error.response.data.message },
      { status: error.response.status },
    )
  }
}

이 기능을 개발하면서 많은 것을 느꼈다. API의 명세에 없다고 구현을 못하는 것은 아니며 , 다른 방법이 존재할 수 있다는 점과 해당 기능과 연결된 다른 코드에서 꼭 반드시 예외를 생각하고 ,내가 쓴 코드에 대해 뒷일을 항상 생각해야한다는점...을 크게 느꼈던 것 같다.

사이드바

현재 서비스의 사이드바에는 전체 유저 목록이 들어간다. QA때 나왔던 문제는 유저가 실시간으로 반영이 안되는 것 같다 + 유저의 정보를 갱신하면 사이드바에 반영이 되지 않는다 라는 문제였다.

이를 어떻게 해결할 수 있을지 고민하다, ISR방식으로 사이드바의 데이터를 표현하면 해결할 수 있을 것 같았다. 기본적으로 Next에서 제공하는 SSG방식으로는 빌드 타임에 이미 데이터가 결정되어 버려서, 수정된 데이터를 가져오는 것에 한계가 명확했다.

ISR방식은 일정 주기마다 업데이트된 데이터로 다시 페이지를 생성한다. 이렇게 하면 빌드시점에 데이터가 결정되어버리는 문제를 해결할 수 있다고 판단했다. 예를들어 주기를 60초로 지정해버리면, 사용자가 처음 들어온 이후 60초동안은 이미 생성된 페이지를 보여주고, 그 후 60초가 지나면, 새로 만들어진 페이지를 사용자에게 보여주는 방법이다.

마크다운 이미지

이렇게 했을때, 바로 수정사항이 반영될수 있어서 사용자에게 더 좋게 다가올수 있다는 장점이 존재했다. 따라서 revalidate를 5초로 잡고, 바로바로 수정사항이 반영되도록 사용자에게 보여지게 하였다.!

(찾아보니 비슷한 내용을 ISR방식으로 해결하신 기술블로그..가 있어서 되게 신기했다.!)

ReactQuery + ISR 적용기

좋았던 점

스크럼을 매일 30분-1시간가량 했는데 이때 다른팀원이 무엇에서 해매고 있는지, 어떤 기능을 개발중인지 명확하게 알 수 있어서 매우 좋았다.

또한 따로 UI라이브러를 쓰진 않았는데 공통적인 컴포넌트를 만드는 것에 있어서 여러 코드를 뒤져보며 많이 배울 수 있었던 것 같다. 나는 이미지 업로드,아바타 2개의 공용 컴포넌트를 개발했는데, 디자인 시스템 찾아가서 어떤 props을 받는지 찾아보기도 하고, 다른 팀원이 제시한 의견을 반영하기도 하면서 학습적으로 많이 배운 것 같다.

마크다운 이미지

아쉬운 점

후반으로 갈수록 버그잡고 개발을 빠르게빠르게 하려다보니 리뷰에 있어서 굉장히 소홀했던 것 같다..! 스크럼과 추가적인 회의를 분리하면 어땠을까..하는 아쉬움도 남는다. 스크럼떄 아예 회의를 같이 해버린 경우가 종종있어서, 이걸 좀 분리를 했으면 좋았을 텐데..하는 아쉬움이 남는다.

리액트쿼리에대해 너무 무지한 상태로 일단 돌아가게 구현했던 것 같다. 추가적인 학습을 여러 자료를 보면서 채워나가야만 할 것 같다. (최종 프로젝트 들어가기전에 반드시.!) 새로운 팀의 팀원분이 공유해주신 자료가 너무 좋아서 그 자료를 볼 것 같다.!

react-query-tutorial

너무 끙끙대고 앓았던 문제들이 있었는데 , 이를 좀 빨리 팀원분들과 공유하면 좋았을걸..하는 아쉬움이 남는다.

너무 기술에만 초점을 맞춘게 아닐까..하는 아쉬움도 든다. 기획적으로 좀더 완성도 있게 잡고 갔어야하나...하는 아쉬움이 남았다.!